package asruby.runtime
{
import asruby.lang.RubyModule;
	
public class Binding
{
   /**
     * 'self' at point when the block is defined
     */
    private var self: IRubyObject;
    
    /**
     * frame of method which defined this block
     */
    private  var frame: Frame;
    private var visibility: Visibility;
    private var klass: RubyModule;
    
    /**
     * A reference to all variable values (and names) that are in-scope for this block.
     */
    private var dynamicScope: DynamicScope;
    
    public function  Binding( self:IRubyObject,  frame:Frame,
             visibility:Visibility,  klass:RubyModule,  dynamicScope:DynamicScope) {
        this.self = self;
        this.frame = frame;
        this.visibility = visibility;
        this.klass = klass;
        this.dynamicScope = dynamicScope;
    }
    
    public function  Binding2(frame: Frame, bindingClass: RubyModule, dynamicScope: DynamicScope) {
        this.self = frame.getSelf();
        this.frame = frame;
        this.visibility = frame.getVisibility();
        this.klass = bindingClass;
        this.dynamicScope = dynamicScope;
    }

    public function  cloneBinding(): Binding {
        // We clone dynamic scope because this will be a new instance of a block.  Any previously
        // captured instances of this block may still be around and we do not want to start
        // overwriting those values when we create a new one.
        // ENEBO: Once we make self, lastClass, and lastMethod immutable we can remove duplicate
        var newBlock: Binding = new Binding(self, frame.duplicate(), visibility, klass,
                dynamicScope.cloneScope());

        return newBlock;
    }

    public function  getVisibility(): Visibility {
        return visibility;
    }

    public function  setVisibility(visibility: Visibility): void {
        this.visibility = visibility;
    }
    
    public function  getSelf(): IRubyObject {
        return self;
    }
    
    public function  setSelf(self: IRubyObject): void {
        this.self = self;
    }

    /**
     * Gets the dynamicVariables that are local to this block.   Parent dynamic scopes are also
     * accessible via the current dynamic scope.
     * 
     * @return Returns all relevent variable scoping information
     */
    public function  getDynamicScope(): DynamicScope {
        return dynamicScope;
    }

    /**
     * Gets the frame.
     * 
     * @return Returns a RubyFrame
     */
    public function  getFrame(): Frame {
        return frame;
    }

    /**
     * Gets the klass.
     * @return Returns a RubyModule
     */
    public function  getKlass(): RubyModule {
        return klass;
    }
    
    /**
     * Is the current block a real yield'able block instead a null one
     * 
     * @return true if this is a valid block or false otherwise
     */
    public function  isGiven(): Boolean {
        return true;
    }
}
}